package com.bestcem.xm.member.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.uitls.EnumUtil;
import com.bestcem.xm.component.security.annotation.AuthIgnore;
import com.bestcem.xm.componet.redis.service.RedisService;
import com.bestcem.xm.member.dao.MemberDao;
import com.bestcem.xm.member.entity.pojo.MemberDO;
import com.bestcem.xm.member.enums.MemberTypeEnum;
import com.bestcem.xm.member.mq.message.MemberMessage;
import com.bestcem.xm.member.service.dto.OrganizationDTO;
import com.bestcem.xm.member.util.MemberUtil;
import com.bestcem.xm.member.util.RpcClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.bestcem.xm.member.constant.Constants.EMPLOYEE_STATUS_MAP;

/**
 * 全量联系人 to BI controller 只使用一次，不分层
 *
 * @author yf.wang <yf.wang@idiaoyan.com>
 * @version V1.0
 * @date 2021/9/17
 */
@Slf4j
@RestController
@RequestMapping("/member/bi")
public class InitMemberToBiController {
    @Resource
    private RedisService redisService;

    @Resource
    private RpcClientUtil rpcClientUtil;

    @Resource
    private MemberUtil memberUtil;

    @Resource
    private MemberDao memberDao;

    private static final String BI_INIT_KEY = "MEMBER_BI_INITDATA_KEY";

    @AuthIgnore
    @GetMapping("/initData")
    public XmResultJson<String> initData(Integer batchCount, String orgId) {
        if (Objects.isNull(batchCount)) {
            batchCount = 20000;
        }

        RLock lock = redisService.getLock(BI_INIT_KEY);
        // 设置为3600s超时
        try {
            if (lock.tryLock(3, 3600, TimeUnit.SECONDS)) {
                try {
                    String errmsg = run(batchCount, orgId);
                    if (StringUtils.isNotEmpty(errmsg)) {
                        return XmResultJson.fail(-1, errmsg);
                    }
                    return XmResultJson.success("SUCCESS");
                } finally {
                    lock.unlock();
                }
            }
        } catch (InterruptedException e) {
            log.error("中断异常");
        }
        return XmResultJson.fail(-1, "当前已在处理过程中，无法重复执行操作");
    }

    public String run(Integer batchCount, String orgId) {

        try {
            // 查询总数，获取页数
            Long total = memberDao.countMember(orgId);
            int size = total.intValue() / batchCount;
            if (total.intValue() % batchCount != 0) {
                size++;
            }
            log.error("[MEMBER.bi]数据总数 {} 每批次处理数据 {}", total, batchCount);
            int start = 0;
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < size; i++) {
                log.error("[MEMBER.bi]数据总循环次数 {} 当前次数 {}", size, i + 1);
                List<MemberDO> memberList = memberDao.findMember(orgId, start, batchCount);
                if (CollUtil.isEmpty(memberList)) {
                    continue;
                }
                for (MemberDO member : memberList) {
                    try {
                        // 获取组织信息
                        ServiceResult<OrganizationDTO> organization =
                                rpcClientUtil.getOrganization(member.getOrgId());
                        OrganizationDTO data = organization.getData();
                        MemberMessage message = MemberUtil.memberDoToMemberMessage(member);
                        message.setOrgCode(data.getCode());
                        message.setOrgName(data.getName());
                        String identityType = "";
                        switch (EnumUtil.getEnumByIndex(MemberTypeEnum.class, member.getMemberType())) {
                            case INSTITUTION:
                                message.setIdentityType("企业对接人");
                                message.setNumberId("000");
                                break;
                            case INTERIOR:
                                identityType = ObjectUtil.isNotEmpty(member.getEmployeeStatus()) ? EMPLOYEE_STATUS_MAP.get(member.getEmployeeStatus()) : "";
                                message.setIdentityType(identityType);
                                break;
                            case INDIVIDUAL:
                                identityType = memberUtil.getIdentityType(member.getPhone(), member.getOrgId(), member.getEmail());
                                message.setIdentityType(identityType);
                                break;
                        }
                        memberUtil.publishCreateMember(message);
                    } catch (Exception e) {
                        log.error("[MEMBER.bi]数据处理失败 {} ", member.getId(), e);
                    }
                }
                start += batchCount;
            }
            long endTime = System.currentTimeMillis();
            log.error("[MEMBER.bi]数据处理完成 总耗时：{} 秒", (endTime - startTime) / 1000);
        } catch (Exception e) {
            String errmsg = String.format("[MEMBER.bi]数据处理失败 e:[%s]", e.toString());
            log.error(errmsg);
            return errmsg;
        }
        return null;
    }


    @AuthIgnore
    @GetMapping("/repairData")
    public String repairData(String time) {
        if (StrUtil.isBlank(time)) {
            // 默认时间
            time = "2022-04-22";
        }
        int start = 0;
        int batchCount = 20000;
        log.error("开始获取时间在 {} 之后的联系人", time);
        List<MemberDO> memberList = null;
        do {
            memberList = memberDao.findByUpdateTimeAfter(time, start, batchCount);
            if (CollUtil.isNotEmpty(memberList)) {
                log.error("本次获取 {} 条联系人数据", memberList.size());
                // 根据 组织id 分组
                Map<String, List<MemberDO>> memberMap =
                        memberList.stream().collect(Collectors.groupingBy(MemberDO::getOrgId));
                if (CollUtil.isNotEmpty(memberMap)) {
                    memberMap.forEach((orgId, members) -> {
                        ServiceResult<OrganizationDTO> organization =
                                rpcClientUtil.getOrganization(orgId);
                        OrganizationDTO data = organization.getData();
                        for (MemberDO member : members) {
                            try {
                                MemberMessage message = MemberUtil.memberDoToMemberMessage(member);
                                if (ObjectUtil.isEmpty(data)) {
                                    log.error("根据 {} 获取组织详情为null", orgId);
                                    message.setOrgCode(data.getCode());
                                    message.setOrgName(data.getName());
                                }
                                String identityType = "";
                                switch (EnumUtil.getEnumByIndex(MemberTypeEnum.class, member.getMemberType())) {
                                    case INSTITUTION:
                                        message.setIdentityType("企业对接人");
                                        message.setNumberId("000");
                                        break;
                                    case INTERIOR:
                                        identityType = ObjectUtil.isNotEmpty(member.getEmployeeStatus()) ? EMPLOYEE_STATUS_MAP.get(member.getEmployeeStatus()) : "";
                                        message.setIdentityType(identityType);
                                        break;
                                    case INDIVIDUAL:
                                        identityType = memberUtil.getIdentityType(member.getPhone(), member.getOrgId(), member.getEmail());
                                        message.setIdentityType(identityType);
                                        break;
                                }
                                memberUtil.publishCreateMember(message);
                            } catch (Exception e) {
                                log.error("[MEMBER.bi]数据处理失败 {} ", member.getId(), e);
                            }
                        }
                    });
                }
                start += batchCount;
            }
        } while (memberList != null && memberList.size() > 0);
        log.error("处理结束");
        return "success";
    }
}
